#include "iotcpbase.h"
#include "ioeventloop.h"
#include "iothreadpool.h"


uvNameSpaceBegin

static void connect_cb(evutil_socket_t fd, short event, void *arg)
{
	io_tcp_i* tcp = (io_tcp_i*)(arg);

	if (event == EV_WRITE) {
		int err;
		socklen_t len = sizeof(err);
		getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&err, (socklen_t*)&len);
	
		if (err) {
			tcp->tcp_fun_cb(tcp, IO_TCP_CONNECTFAIL);
		}
		else {
			tcp->tcp_fun_cb(tcp, IO_TCP_CONNECTED);
		}
	}
	else {
		tcp->tcp_fun_cb(tcp, IO_TCP_CONNECTFAIL);
	}
}

int	io_tcp_init(io_tcp_i* pTcp) {

	io_thread_t* p = geteventloop();
	pTcp->eventloop = p->eventloop;
	return 1;
}
int	io_tcp_uninit(io_tcp_i* pTcp) {

	return 1;
}
int io_tcp_open(io_tcp_i *pTcp, os_sock_t sock) {

	pTcp->sock = sock;
	evutil_make_socket_nonblocking(pTcp->sock);
	pTcp->ev = event_new(pTcp->eventloop->loop, pTcp->sock,EV_WRITE, connect_cb, pTcp);
	return 1;
}
int io_tcp_listen(io_tcp_i *pTcp) {

	return 1;
}
int io_tcp_connect(io_tcp_i *pTcp, void* data, const char* ipaddress, unsigned long iport,int itimeout) {

	struct sockaddr_in addr;
	unsigned short uport = iport & UINT16_MAX;

	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(ipaddress);

	addr.sin_port = htons(uport);
	pTcp->io.pdata = data;

	if (connect(pTcp->sock, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == -1) {

		int error = 0;
		socklen_t len = sizeof(error);
		int res = getsockopt(pTcp->sock, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
		if (res == 0 && error == 0) {
			struct timeval tv1;
			tv1.tv_sec = itimeout;
			tv1.tv_usec = 0;
			if (event_add(pTcp->ev, &tv1) == 0)
				return 1;
		}
	}
	return -1;
}
int io_tcp_connect6(io_tcp_i *pTcp, void* data, const char* ipaddress, int iport) {

	return 1;
}
int io_tcp_bind(io_tcp_i *pTcp, const char* ipaddress, int iport) {

	return 1;
}
int io_tcp_bind6(io_tcp_i *pTcp, const char* ipaddress, int iport) {

	return 1;
}
uvNameSpaceEnd
